package cn.virens.config;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Properties;

import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.alibaba.druid.pool.DruidDataSource;
import com.github.pagehelper.PageInterceptor;

import cn.virens.database.common.TransactionExecute;
import cn.virens.util.ResourceUtil;
import tk.mybatis.mapper.code.Style;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;

/**
 * 数据库配置
 * 
 * @文件   :DataSourceConfig.java
 * @作者   :cn.loioi
 * @创建时间 :2016年10月13日 下午1:11:48
 */
@Configuration
@EnableTransactionManagement
@ComponentScan("cn.virens.database.serviceimpl")
public class SpringDataSourceConfig {
	@Value("${jdbc.url}")
	private String jdbcUrl;

	@Value("${jdbc.username}")
	private String jdbcUsername;

	@Value("${jdbc.password}")
	private String jdbcPassword;

	@Value("${jdbc.driverClass}")
	private String jdbcDriverClass;

	/**
	 * mysql事务管理
	 * 
	 * @return
	 */
	@Bean(name = "txManager")
	public PlatformTransactionManager txManager(@Qualifier("druidDataSource") DruidDataSource druidDataSource) {
		return new DataSourceTransactionManager(druidDataSource);
	}

	@Bean(name = "txExecute")
	public TransactionExecute txExecute(@Qualifier("txManager") PlatformTransactionManager manager) {
		return new TransactionExecute(manager);
	}

	/**
	 * MyBatis 数据连接地址池配置
	 * 
	 * @throws IOException
	 * @throws SQLException
	 */
	@Bean(name = "druidDataSource", destroyMethod = "close")
	public DruidDataSource druidDataSource(Environment env) throws SQLException {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setUrl(jdbcUrl);
		dataSource.setUsername(jdbcUsername);
		dataSource.setPassword(jdbcPassword);
		dataSource.setDriverClassName(jdbcDriverClass);
		// 配置初始化大小、最小、最大
		dataSource.setInitialSize(1);
		dataSource.setMinIdle(1);
		dataSource.setMaxActive(20);
		dataSource.setMaxWait(60000);// 配置获取连接等待超时的时间

		dataSource.setTimeBetweenEvictionRunsMillis(60000);// 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
		dataSource.setMinEvictableIdleTimeMillis(300000);// 配置一个连接在池中最小生存的时间，单位是毫秒
		dataSource.setDefaultAutoCommit(false);// 禁止自动提交，实现事务管理

		dataSource.setValidationQuery("SELECT 1;");
		dataSource.setValidationQueryTimeout(30000);

		dataSource.setTestWhileIdle(true);
		dataSource.setTestOnBorrow(false);
		dataSource.setTestOnReturn(false);

		dataSource.setPoolPreparedStatements(true);
		dataSource.setMaxPoolPreparedStatementPerConnectionSize(50);

		// 拦截配置
		dataSource.setFilters("stat,wall");

		return dataSource;
	}

	/**
	 * MyBatis配置 :配置sqlSessionFactory
	 * 
	 * @return
	 * @throws Exception
	 */
	@Bean("sqlSessionFactoryBean")
	public SqlSessionFactoryBean sqlSessionFactoryBean(DruidDataSource druidDataSource) throws Exception {
		// 分页拦截器
		PageInterceptor interceptor = new PageInterceptor();
		Properties properties = new Properties();
		properties.put("helperDialect", "mysql");

		interceptor.setProperties(properties);

		// 创建SqlSession工厂
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(druidDataSource);
		sqlSessionFactoryBean.setPlugins(new Interceptor[] { interceptor });
		sqlSessionFactoryBean.setMapperLocations(ResourceUtil.getResources("classpath:mysql/**/*.xml"));

		return sqlSessionFactoryBean;
	}

	@Bean
	public static MapperScannerConfigurer mapperScannerConfigurer() {
		MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
		mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
		mapperScannerConfigurer.setBasePackage("cn.virens.database.mysql.mapper");
		mapperScannerConfigurer.getMapperHelper().getConfig().setIDENTITY("MYSQL");
		mapperScannerConfigurer.getMapperHelper().getConfig().setStyle(Style.normal);
		mapperScannerConfigurer.getMapperHelper().getConfig().setWrapKeyword("`{0}`");

		return mapperScannerConfigurer;
	}
}